Completed
Pull Request — develop (#81)
by Xaver
01:12
created

node.js ➔ ... ➔ getName   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
c 0
b 0
f 0
nc 2
dl 0
loc 3
rs 10
nop 1
1
define(['sorttable', 'virtual-dom', 'd3-interpolate', 'moment', 'helper'],
2
  function (SortTable, V, d3Interpolate, moment, helper) {
3
    'use strict';
4
5
    function getName(d) {
6
      return (d.node ? d.node.nodeinfo.hostname : d.id);
7
    }
8
9
    function showGeoURI(d) {
10
      if (!helper.hasLocation(d)) {
11
        return undefined;
12
      }
13
14
      return function (el) {
15
        var a = document.createElement('a');
16
        a.textContent = Number(d.nodeinfo.location.latitude.toFixed(6)) + ', ' + Number(d.nodeinfo.location.longitude.toFixed(6));
17
        a.href = 'geo:' + d.nodeinfo.location.latitude + ',' + d.nodeinfo.location.longitude;
18
        el.appendChild(a);
19
      };
20
    }
21
22
    function showStatus(d) {
23
      return function (el) {
24
        el.classList.add(d.flags.unseen ? 'unseen' : (d.flags.online ? 'online' : 'offline'));
25
        el.textContent = _.t((d.flags.online ? 'node.lastOnline' : 'node.lastOffline'), {
26
          time: d.lastseen.fromNow(),
27
          date: d.lastseen.format('DD.MM.YYYY, H:mm:ss')
28
        });
29
      };
30
    }
31
32
    function showFirmware(d) {
33
      var release = helper.dictGet(d.nodeinfo, ['software', 'firmware', 'release']);
34
      var base = helper.dictGet(d.nodeinfo, ['software', 'firmware', 'base']);
35
36
      if (release === null || base === null) {
37
        return undefined;
38
      }
39
40
      return release + ' / ' + base;
41
    }
42
43
    function showSite(d, config) {
44
      var site = helper.dictGet(d.nodeinfo, ['system', 'site_code']);
45
      var rt = site;
46
      if (config.siteNames) {
47
        config.siteNames.forEach(function (t) {
48
          if (site === t.site) {
49
            rt = t.name;
50
          }
51
        });
52
      }
53
      return rt;
54
    }
55
56
    function showUptime(d) {
57
      if (!('uptime' in d.statistics)) {
58
        return undefined;
59
      }
60
61
      return moment.duration(d.statistics.uptime, 'seconds').humanize();
62
    }
63
64
    function showFirstseen(d) {
65
      if (!('firstseen' in d)) {
66
        return undefined;
67
      }
68
69
      return d.firstseen.fromNow(true);
70
    }
71
72
    function showClients(d) {
73
      if (!d.flags.online) {
74
        return undefined;
75
      }
76
77
      return function (el) {
78
        el.appendChild(document.createTextNode(d.statistics.clients > 0 ? d.statistics.clients : _.t('none')));
79
        el.appendChild(document.createElement('br'));
80
81
        var span = document.createElement('span');
82
        span.classList.add('clients');
83
        span.innerHTML = '<i class="ion-person"></i>'.repeat(d.statistics.clients);
84
        el.appendChild(span);
85
      };
86
    }
87
88
    function showIPs(d) {
89
      var ips = helper.dictGet(d.nodeinfo, ['network', 'addresses']);
90
      if (ips === null) {
91
        return undefined;
92
      }
93
94
      ips.sort();
95
96
      return function (el) {
97
        ips.forEach(function (ip, i) {
98
          var link = !ip.startsWith('fe80:');
99
100
          if (i > 0) {
101
            el.appendChild(document.createElement('br'));
102
          }
103
104
          if (link) {
105
            var a = document.createElement('a');
106
            a.href = 'http://[' + ip + ']/';
107
            a.textContent = ip;
108
            el.appendChild(a);
109
          } else {
110
            el.appendChild(document.createTextNode(ip));
111
          }
112
        });
113
      };
114
    }
115
116
    function showBar(v, width, warning) {
117
      var span = document.createElement('span');
118
      span.classList.add('bar');
119
120
      var bar = document.createElement('span');
121
      bar.style.width = (width * 100) + '%';
122
      if (warning) {
123
        span.classList.add('warning');
124
      }
125
      span.appendChild(bar);
126
127
      var label = document.createElement('label');
128
      label.textContent = v;
129
      span.appendChild(label);
130
131
      return span;
132
    }
133
134
    function showLoad(d) {
135
      if (!('loadavg' in d.statistics)) {
136
        return undefined;
137
      }
138
139
      return function (el) {
140
        var value = d.statistics.loadavg.toFixed(2);
141
        var width = d.statistics.loadavg % 1;
142
        var warning = false;
143
        if (d.statistics.loadavg >= d.nodeinfo.hardware.nproc) {
144
          warning = true;
145
        }
146
        el.appendChild(showBar(value, width, warning));
147
      };
148
    }
149
150
    function showRAM(d) {
151
      if (!('memory_usage' in d.statistics)) {
152
        return undefined;
153
      }
154
155
      return function (el) {
156
        var value = Math.round(d.statistics.memory_usage * 100) + ' %';
157
        var width = d.statistics.memory_usage;
158
        var warning = false;
159
        if (d.statistics.memory_usage >= 0.8) {
160
          warning = true;
161
        }
162
        el.appendChild(showBar(value, width, warning));
163
      };
164
    }
165
166
    function showAutoupdate(d) {
167
      var au = helper.dictGet(d.nodeinfo, ['software', 'autoupdater']);
168
      if (!au) {
169
        return undefined;
170
      }
171
172
      return au.enabled ? _.t('node.activated', { branch: au.branch }) : _.t('node.deactivated');
173
    }
174
175
    function showStatImg(o, d) {
176
      var subst = {};
177
      subst['{NODE_ID}'] = d.nodeinfo.node_id ? d.nodeinfo.node_id : _.t('unknown');
178
      subst['{NODE_NAME}'] = d.nodeinfo.hostname ? d.nodeinfo.hostname.replace(/[^a-z0-9\-]/ig, '_') : _.t('unknown');
179
      subst['{TIME}'] = d.lastseen.format('DDMMYYYYHmmss');
180
      subst['{LOCALE}'] = _.locale();
181
      return helper.showStat(o, subst);
182
    }
183
184
    return function (config, el, router, d) {
185
      var linkScale = d3Interpolate.interpolate('#F02311', '#04C714');
186
187
      function renderNeighbourRow(n) {
188
        var icons = [];
189
        var name = [];
190
        var unknown = !(n.node);
191
192
        icons.push(V.h('span', { className: n.incoming ? 'ion-arrow-left-c' : 'ion-arrow-right-c' }));
193
        if (!unknown && helper.hasLocation(n.node)) {
194
          icons.push(V.h('span', { className: 'ion-location' }));
195
        }
196
197
        if (!unknown) {
198
          name.push(V.h('a', { href: router.getUrl({ n: n.node.nodeinfo.node_id }), onclick: router.node(n.node), className: 'online' }, n.node.nodeinfo.hostname));
199
        } else {
200
          name.push(n.link.id);
201
        }
202
203
        var td1 = V.h('td', icons);
204
        var td2 = V.h('td', name);
205
        var td3 = V.h('td', (n.node.statistics.clients ? n.node.statistics.clients.toString() : '0'));
206
        var td4 = V.h('td', { style: { color: linkScale(1 / n.link.tq) } }, helper.showTq(n.link));
207
        var td5 = V.h('td', n.link.type);
208
        var td6 = V.h('td', helper.showDistance(n.link));
209
210
        return V.h('tr', [td1, td2, td3, td4, td5, td6]);
211
      }
212
213
      var h2 = document.createElement('h2');
214
      h2.textContent = d.nodeinfo.hostname;
215
      el.appendChild(h2);
216
217
      var attributes = document.createElement('table');
218
      attributes.classList.add('attributes');
219
220
      helper.attributeEntry(attributes, 'node.status', showStatus(d));
221
      helper.attributeEntry(attributes, 'node.gateway', d.flags.gateway ? 'ja' : null);
222
      helper.attributeEntry(attributes, 'node.coordinates', showGeoURI(d));
223
224
      if (config.nodeInfobox && config.nodeInfobox.contact) {
225
        helper.attributeEntry(attributes, 'node.contact', helper.dictGet(d.nodeinfo, ['owner', 'contact']));
226
      }
227
228
      helper.attributeEntry(attributes, 'node.hardware', helper.dictGet(d.nodeinfo, ['hardware', 'model']));
229
      helper.attributeEntry(attributes, 'node.primaryMac', helper.dictGet(d.nodeinfo, ['network', 'mac']));
230
      helper.attributeEntry(attributes, 'node.id', helper.dictGet(d.nodeinfo, ['node_id']));
231
      helper.attributeEntry(attributes, 'node.firmware', showFirmware(d));
232
      helper.attributeEntry(attributes, 'node.site', showSite(d, config));
233
      helper.attributeEntry(attributes, 'node.uptime', showUptime(d));
234
      helper.attributeEntry(attributes, 'node.firstSeen', showFirstseen(d));
235
      if (config.nodeInfobox && config.nodeInfobox.hardwareUsage) {
236
        helper.attributeEntry(attributes, 'node.systemLoad', showLoad(d));
237
        helper.attributeEntry(attributes, 'node.ram', showRAM(d));
238
      }
239
      helper.attributeEntry(attributes, 'node.ipAddresses', showIPs(d));
240
      helper.attributeEntry(attributes, 'node.selectedGateway', helper.dictGet(d.statistics, ['gateway']));
241
      helper.attributeEntry(attributes, 'node.update', showAutoupdate(d));
242
      helper.attributeEntry(attributes, 'node.clients', showClients(d));
243
244
      el.appendChild(attributes);
245
246
      if (d.neighbours.length > 0) {
247
        var h3 = document.createElement('h3');
248
        h3.textContent = _.t('node.link', d.neighbours.length) + '(' + d.neighbours.length + ')';
249
        el.appendChild(h3);
250
251
        var headings = [{
252
          name: ''
253
        }, {
254
          name: 'node.nodes',
255
          sort: function (a, b) {
256
            return getName(a).localeCompare(getName(b));
257
          },
258
          reverse: false
259
        }, {
260
          name: 'node.clients',
261
          class: 'ion-people',
262
          sort: function (a, b) {
263
            return ('clients' in a.node.statistics ? a.node.statistics.clients : -1) -
264
              ('clients' in b.node ? b.node.statistics.clients : -1);
265
          },
266
          reverse: true
267
        }, {
268
          name: 'node.tq',
269
          class: 'ion-connection-bars',
270
          sort: function (a, b) {
271
            return a.link.tq - b.link.tq;
272
          },
273
          reverse: true
274
        }, {
275
          name: 'node.linkType',
276
          class: 'ion-share-alt',
277
          sort: function (a, b) {
278
            return a.link.type.localeCompare(b.link.type);
279
          },
280
          reverse: false
281
        }, {
282
          name: 'node.distance',
283
          class: 'ion-arrow-resize',
284
          sort: function (a, b) {
285
            return (a.link.distance === undefined ? -1 : a.link.distance) -
286
              (b.link.distance === undefined ? -1 : b.link.distance);
287
          },
288
          reverse: true
289
        }];
290
291
        var table = new SortTable(headings, 1, renderNeighbourRow);
292
        table.el.classList.add('node-links');
293
        table.setData(d.neighbours);
294
295
        el.appendChild(table.el);
296
      }
297
298
      if (config.nodeInfos) {
299
        config.nodeInfos.forEach(function (nodeInfo) {
300
          var h4 = document.createElement('h4');
301
          h4.textContent = nodeInfo.name;
302
          el.appendChild(h4);
303
          el.appendChild(showStatImg(nodeInfo, d));
304
        });
305
      }
306
    };
307
  });
308